﻿#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <unordered_set>
#include <algorithm>
#include <chrono>
#include <sstream>

using namespace std;
using namespace std::chrono;

const int QUERY_NUM = 1000;

// 倒排列表集合
vector<vector<unsigned int>> index_lists;

// 查询关键词
vector<vector<unsigned int>> queries;

// 结果列表集合
vector<vector<unsigned int>> res_lists;

// 按列表求交
void Intersection_ByList();

// 结果文件写入
void res_writing();

int main() {
    // 打开index文件
    ifstream index_file("ExpIndex", ios::binary);
    if (!index_file.is_open()) {
        cout << "无法打开Index文件！" << endl;
        return 1;
    }


    // 读取index文件至内存
    while (!index_file.eof()) {
        int length;
        index_file.read(reinterpret_cast<char*>(&length), sizeof(length));
        vector<unsigned int> temp_list(length);
        index_file.read(reinterpret_cast<char*>(&temp_list[0]), length * sizeof(unsigned int));
        index_lists.push_back(temp_list);
    }
    index_file.close();

    // 打开query文件
    ifstream query_file("ExpQuery.txt");
    if (!query_file.is_open()) {
        cout << "无法打开Query文件！" << endl;
        return 1;
    }

    // 读取query文件至内存
    string line;
    while (getline(query_file, line)) {
        vector<unsigned int> query;
        istringstream iss(line);
        unsigned int num;
        while (iss >> num) {
            query.push_back(num);
        }
        query.insert(query.begin(), query.size());
        queries.push_back(query);
    }
    query_file.close();

    // 按列表求交
    Intersection_ByList();

    // 结果文件写入
    res_writing();

    return 0;
}

void Intersection_ByList() {
    cout << "正在运行：按列表求交..." << endl;
    auto start = high_resolution_clock::now();//记录开始时间
    for (int i = 0; i < QUERY_NUM; i++) {
        cout << "查询记录[" << i + 1 << "]\n";
        // 第一个列表做为初始结果集合
        unordered_set<unsigned int> S(index_lists[queries[i][1]].begin(), index_lists[queries[i][1]].end());
        //遍历其他列表
        for (int j = 2; j <= queries[i][0]; j++) {
            unordered_set<unsigned int> tmp(index_lists[queries[i][j]].begin(), index_lists[queries[i][j]].end());
            for (auto it = S.begin(); it != S.end();) {
                if (tmp.find(*it) == tmp.end()) {
                    it = S.erase(it);//求交
                }
                else {
                    it++;
                }
            }
        }
        // 将结果存入结果集合
        res_lists.push_back(vector<unsigned int>(S.begin(), S.end()));
    }
    auto stop = high_resolution_clock::now();//记录结束时间
    auto duration = duration_cast<milliseconds>(stop - start);
    cout << "按列表用时：" << duration.count() << "ms" << endl;
}

void res_writing() {
    cout << "正在运行：结果文件写入..." << endl;
    // 打开结果文件
    ofstream ofile("result.txt");
    if (!ofile.is_open()) {
        cout << "无法打开输出文件！" << endl;
        return;
    }

    // 写入结果到文件
    for (int i = 0; i < QUERY_NUM; i++) {
        ofile << "keywords: ";

        for (int j = 1; j <= queries[i][0]; j++) {
            ofile << queries[i][j] << " ";
        }
        ofile << endl << "result: ";
        for (int j = 0; j < res_lists[i].size(); j++) {
            ofile << res_lists[i][j] << " ";
        }
        ofile << endl;
    }
    ofile.close();
}
